class Watcher{
    constructor(vm,expr,cb){
        this.vm = vm
        this.expr = expr
        this.cb = cb
        //先把旧值保存
        this.oldVal = this.getOldVal()
    }
    update(){
        const newVal = compileUtil.getVal(this.expr,this.vm)
        if(newVal !== this.oldVal){
            this.cb(newVal)
        }
    }
    getOldVal(){
        Dep.target = this
        const oldVal =  compileUtil.getVal(this.expr,this.vm)
        Dep.target = null
        return oldVal
    }
}
class Dep{
    constructor(){
        this.subs = [];
    }
    //收集观察者
    addSub(watcher){
        this.subs.push(watcher)
    }
    //通知观察者去更新
    notify(){
        this.subs.forEach(w=>w.update())
    }
}
class Observer{
    constructor(data){
        this.observer(data)
    }
    observer(data){
        if(data && typeof data === 'object'){
           Object.keys(data).forEach(key=>{
               this.defineReactive(data,key,data[key])
           })
        }
    }
    defineReactive(obj,key,value){
        //递归遍历
        this.observer(value)
        //劫持数据
        const dep = new Dep()
        // 使用Object.defineProperty()方法可以更方便的监听一个对象的变化
        Object.defineProperty(obj,key,{
            enumerable:true,
            configurable:false,
            get(){
                //订阅数据变化时，往Dep中添加观察者
                Dep.target && dep.addSub(Dep.target)
                return value
            },
            set:(newVal)=>{
                this.observer(newVal)
                if(newVal !== value){
                    value = newVal
                }
                //高速Dep通知变化
                dep.notify()
            }
        })
    }
}
